using System;
using System.Collections.Generic;
using System.Text;
using Word = Microsoft.Office.Interop.Word;
using Excel = Microsoft.Office.Interop.Excel;
using PowerPoint = Microsoft.Office.Interop.PowerPoint;
using Microsoft.Office.Core;
using Utility = PHSRAG.Utility;


namespace InsightServiceUtility
{
	public enum FileCompStatus
	{
		isProtected = -1,
		isIdentical,
		isDiff
	}

	public class AutomationDocumentHelper
	{


		public AutomationDocumentHelper()
		{
		}

		public static class FileType
		{			
			public const string Word = ".DOC";
			public const string wordMacro = ".DOCM";
			public const string Word2007 = ".DOCX";
			public const string Dot = ".DOT";
			public const string Dot2007 = ".DOTX";
			public const string DotMacro = ".DOTM";
			public const string RTF = ".RTF";
            public const string TXT = ".TXT";
            public const string HTM = ".HTM";
            public const string HTML = ".HTML";

			
			public const string Excel = ".XLS";
			public const string ExcelMacro = ".XLM";
			public const string Excel2007 = ".XLSX";
			public const string PowerPoint2007 = ".PPTX";
			public const string PowerPoint = ".PPT";
		}

		public static void ConvertToPDF(string sourceFilePath, string exportFilePath, string sourceFileType)
		{
			switch (sourceFileType.ToUpper())
			{
				case FileType.Word:
				case FileType.wordMacro:
				case FileType.Word2007:
				case FileType.Dot:
				case FileType.Dot2007:
				case FileType.DotMacro:
				case FileType.RTF:
                case FileType.TXT:
                case FileType.HTM:
                case FileType.HTML:     
					ConvertWordToPDF(sourceFilePath, exportFilePath);
					return;
				case FileType.Excel:
				case FileType.ExcelMacro:
				case FileType.Excel2007:
					ConvertExcelToPDF(sourceFilePath, exportFilePath);
					return;
				case FileType.PowerPoint:
				case FileType.PowerPoint2007:
					ConvertPPTToPDF(sourceFilePath, exportFilePath);
					return;
				default:
					DocumentHelper.ConvertToPDF(sourceFilePath, Utility.Settings.GetKeyValue(DocumentHelper.PDFConversionTimeOut, DocumentHelper.PDFConversionDefaultTimeOut), exportFilePath);
					return;
			}
		}

		/// <summary>
		/// Convert Word To Pdf
		/// </summary>
		/// <param name="sourceFilePath">Name and Path of the word document to be converted</param>
		/// <param name="exportFilePath">Name and Path of the destination (pdf) file</param>
		public static void ConvertWordToPDF(string sourceFilePath, string exportFilePath)
		{
			object objSourceFilePath = (object)sourceFilePath;
			Word.ApplicationClass wordApplication = new Word.ApplicationClass();
			Word.Document wordDocument = null;
			object paramMissing = Type.Missing;
			Word.WdExportFormat paramExportFormat = Word.WdExportFormat.wdExportFormatPDF;
			bool paramOpenAfterExport = false;
			Word.WdExportOptimizeFor paramExportOptimizeFor = Word.WdExportOptimizeFor.wdExportOptimizeForPrint;
			Word.WdExportRange paramExportRange = Word.WdExportRange.wdExportAllDocument;
			int paramStartPage = 0;
			int paramEndPage = 0;
			Word.WdExportItem paramExportItem = Word.WdExportItem.wdExportDocumentContent;
			bool paramIncludeDocProps = true;
			bool paramKeepIRM = true;
			Word.WdExportCreateBookmarks paramCreateBookmarks = Word.WdExportCreateBookmarks.wdExportCreateWordBookmarks;
			bool paramDocStructureTags = true;
			bool paramBitmapMissingFonts = true;
			bool paramUseISO19005_1 = false;

			try
			{
				wordApplication.AutomationSecurity = MsoAutomationSecurity.msoAutomationSecurityForceDisable;//disable macros
				wordApplication.DisplayAlerts = Microsoft.Office.Interop.Word.WdAlertLevel.wdAlertsNone;
				object objectReadOnly = true;
				// Open the source document.
				wordDocument = wordApplication.Documents.Open(
					ref objSourceFilePath, ref paramMissing, ref objectReadOnly,
					ref paramMissing, ref paramMissing, ref paramMissing,
					ref paramMissing, ref paramMissing, ref paramMissing,
					ref paramMissing, ref paramMissing, ref paramMissing,
					ref paramMissing, ref paramMissing, ref paramMissing,
					ref paramMissing);

				// Export it in the specified format.
				if (wordDocument != null)
				{
					wordDocument.ExportAsFixedFormat(exportFilePath,
						paramExportFormat, paramOpenAfterExport,
						paramExportOptimizeFor, paramExportRange, paramStartPage,
						paramEndPage, paramExportItem, paramIncludeDocProps,
						paramKeepIRM, paramCreateBookmarks, paramDocStructureTags,
						paramBitmapMissingFonts, paramUseISO19005_1,
						ref paramMissing);
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				// Close and release the Document object.
				if (wordDocument != null)
				{
					object SaveChanges = false;
					wordDocument.Close(ref SaveChanges, ref paramMissing, ref paramMissing);
					wordDocument = null;
				}

				// Quit Word and release the ApplicationClass object.
				if (wordApplication != null)
				{
					object SaveChanges = false;
					wordApplication.Quit(ref SaveChanges, ref paramMissing, ref paramMissing);
					wordApplication = null;
				}

				GC.Collect();
				GC.WaitForPendingFinalizers();
				GC.Collect();
				GC.WaitForPendingFinalizers();
			}

		}

		/// <summary>
		/// Convert Excel To Pdf
		/// </summary>
		/// <param name="sourceFilePath">Name and Path of the excel file to be converted</param>
		/// <param name="exportFilePath">Name and Path of the destination (pdf) file</param>
		public static void ConvertExcelToPDF(string sourceFilePath, string exportFilePath)
		{
			Excel.ApplicationClass excelApplication = new Excel.ApplicationClass();
			Excel.Workbook excelWorkBook = null;
			object paramMissing = Type.Missing;

			Excel.XlFixedFormatType paramExportFormat = Excel.XlFixedFormatType.xlTypePDF;
			Excel.XlFixedFormatQuality paramExportQuality =
				Excel.XlFixedFormatQuality.xlQualityStandard;
			bool paramOpenAfterPublish = false;
			bool paramIncludeDocProps = true;
			bool paramIgnorePrintAreas = true;
			object paramFromPage = Type.Missing;
			object paramToPage = Type.Missing;

			try
			{

				excelApplication.DisplayAlerts = false;
				excelApplication.AutomationSecurity = MsoAutomationSecurity.msoAutomationSecurityForceDisable;
				object objectReadOnly = true;
				// Open the source workbook.
				excelWorkBook = excelApplication.Workbooks.Open(sourceFilePath,
					paramMissing, objectReadOnly, paramMissing, paramMissing,
					paramMissing, paramMissing, paramMissing, paramMissing,
					paramMissing, paramMissing, paramMissing, paramMissing,
					paramMissing, paramMissing);

				// Save it in the target format.
				if (excelWorkBook != null)
				{
					excelWorkBook.ExportAsFixedFormat(paramExportFormat,
						exportFilePath, paramExportQuality,
						paramIncludeDocProps, paramIgnorePrintAreas, paramFromPage,
						paramToPage, paramOpenAfterPublish,
						paramMissing);
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				// Close the workbook object.
				if (excelWorkBook != null)
				{
					excelWorkBook.Close(false, paramMissing, paramMissing);
					excelWorkBook = null;
				}

				// Quit Excel and release the ApplicationClass object.
				if (excelApplication != null)
				{
					excelApplication.Quit();
					excelApplication = null;
				}

				GC.Collect();
				GC.WaitForPendingFinalizers();
				GC.Collect();
				GC.WaitForPendingFinalizers();
			}

		}

		/// <summary>
		/// Convert Powerpoint to pDF
		/// </summary>
		/// <param name="sourceFilePath">Name and Path of the ppt file to be converted</param>
		/// <param name="exportFilePath">Name and Path of the destination(pdf) file</param>
		public static void ConvertPPTToPDF(string sourceFilePath, string exportFilePath)
		{
			PowerPoint.Application pptApplication = new PowerPoint.ApplicationClass();
			PowerPoint.Presentation presentation = null;
			object paramMissing = Type.Missing;

			PowerPoint.PpFixedFormatType paramExportFormat = PowerPoint.PpFixedFormatType.ppFixedFormatTypePDF;
			PowerPoint.PpFixedFormatIntent formatIntent = PowerPoint.PpFixedFormatIntent.ppFixedFormatIntentPrint;
			MsoTriState frameSlides = MsoTriState.msoFalse;
			PowerPoint.PpPrintHandoutOrder handoutOrder = PowerPoint.PpPrintHandoutOrder.ppPrintHandoutVerticalFirst;
			PowerPoint.PpPrintOutputType printOutputType = PowerPoint.PpPrintOutputType.ppPrintOutputSlides;
			MsoTriState printHiddenSlides = MsoTriState.msoFalse;
			PowerPoint.PrintRange printRange = null;
			PowerPoint.PpPrintRangeType printRangeType = PowerPoint.PpPrintRangeType.ppPrintAll;
			string slideShowName = null;
			bool includeDocProperties = true;
			bool keepIRMSettings = true;
			bool docStructureTags = true;
			bool bitmapMissingFonts = true;
			bool useISO19005_1 = false;
			object externalExporter = Type.Missing;

			try
			{
				pptApplication.DisplayAlerts = Microsoft.Office.Interop.PowerPoint.PpAlertLevel.ppAlertsNone;
				pptApplication.AutomationSecurity = MsoAutomationSecurity.msoAutomationSecurityForceDisable;
				// Open the source document.
				presentation = pptApplication.Presentations.Open(
					sourceFilePath, MsoTriState.msoTrue, MsoTriState.msoTrue, MsoTriState.msoFalse);

				// Export it in the specified format.
				if (presentation != null)
					presentation.ExportAsFixedFormat(exportFilePath,
						paramExportFormat, formatIntent, frameSlides, handoutOrder, printOutputType, printHiddenSlides,
						printRange, printRangeType, slideShowName, includeDocProperties, keepIRMSettings, docStructureTags,
						bitmapMissingFonts, useISO19005_1, externalExporter);
			}
			catch (Exception ex)
			{
                EmailNotification.SendEmail("source file path" + sourceFilePath + "\r expt file path: " + exportFilePath + "\r presentation is null:" + (presentation == null));
				throw ex;
			}
			finally
			{
				// Close and release the Document object.
				if (presentation != null)
				{
					presentation.Close();
					presentation = null;
				}

				// Quit Word and release the ApplicationClass object.
				if (pptApplication != null)
				{
					pptApplication.Quit();
					pptApplication = null;
				}

				GC.Collect();
				GC.WaitForPendingFinalizers();
				GC.Collect();
				GC.WaitForPendingFinalizers();
			}
		}

		/// <summary>
		/// Compare 2 word documents. The differences are shown in the first document.
		/// </summary>
		/// <param name="firstDocumentPath">First Document Path</param>
		/// <param name="secondDocumentPath">Second Document Path</param>
		public static int CompareDocuments(object firstDocumentPath, string secondDocumentPath)
		{
			object missing = System.Reflection.Missing.Value;
			object compareTarget = Word.WdCompareTarget.wdCompareTargetCurrent;
			object addToRecentFiles = false;
			object saveFormat = Word.WdSaveFormat.wdFormatRTF;

			object lockComments = System.Reflection.Missing.Value;
			object password = System.Reflection.Missing.Value;
			object writePassword = System.Reflection.Missing.Value;
			object readOnlyRecommended = System.Reflection.Missing.Value;
			object saveNativePictureFormat = System.Reflection.Missing.Value;
			object saveAsAOCELetter = System.Reflection.Missing.Value;
			object lineEnding = System.Reflection.Missing.Value;
			object insertLineBreaks = System.Reflection.Missing.Value;
			object encoding = System.Reflection.Missing.Value;

			// true adds control characters to the output file to preserve bi-directional layout of the 
			// text in the original document.
			object addBiDiMarks = true;
			// true to save TrueType fonts with the document. 
			object embedTrueTypeFonts = false;
			// true to save the data entered by a user in a form as a data record.
			object saveFormsData = true;

			// If the document is saved as a text file, true allows Word to replace some symbols with text
			// that looks similar. For example, displaying the copyright symbol as (c). 
			object allowSubstitutions = false;

			object ignoreComparisonWarnings = true;
			object saveChanges = true;
			object doNotSaveChanges = false;
			object detectFormatChanges = true;

			Word.Application wordApplication = null;
			Word.Document firstDocument = null;

			try
			{
				wordApplication = new Word.ApplicationClass();

				wordApplication.AutomationSecurity = MsoAutomationSecurity.msoAutomationSecurityForceDisable;//disable macros
				wordApplication.DisplayAlerts = Microsoft.Office.Interop.Word.WdAlertLevel.wdAlertsNone;				

				firstDocument = wordApplication.Documents.Open(ref firstDocumentPath, ref missing, ref missing, ref missing, ref missing,
					ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
					ref missing, ref missing, ref missing, ref missing);

				// make sure the file is not protected
				if (firstDocument.ProtectionType != Word.WdProtectionType.wdNoProtection)
					return (int)FileCompStatus.isProtected;

				firstDocument.Compare(secondDocumentPath, ref missing, ref compareTarget, ref detectFormatChanges,
					ref ignoreComparisonWarnings, ref addToRecentFiles, ref missing, ref missing);
				return (int)(firstDocument.Revisions.Count > 0 ? FileCompStatus.isDiff : FileCompStatus.isProtected);
			}
			//Exceptions are bubbled up
			finally
			{
				// Close and release the Document object.
				if (firstDocument != null)
				{
					firstDocument.Close(ref saveChanges, ref missing, ref missing);
					firstDocument = null;
				}

				// Quit Word and release the ApplicationClass object.
				if (wordApplication != null)
				{
					object SaveChanges = false;
					wordApplication.Quit(ref saveChanges, ref missing, ref missing);
					wordApplication = null;
				}
				GC.Collect();
				GC.WaitForPendingFinalizers();
				GC.Collect();
				GC.WaitForPendingFinalizers();
			}

		}
	}
}
